package com.meilingcloud.biobank.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.meilingcloud.biobank.domain.FamilySource;
import com.meilingcloud.biobank.mapper.FamilySourceMapper;
import com.meilingcloud.biobank.service.IFamilySourceService;
import com.meilingcloud.common.exception.CustomException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * 家系样本源 Service业务层处理
 *
 * @author chenl
 * @date 2021-06-22
 */
@Service
public class FamilySourceServiceImpl extends ServiceImpl<FamilySourceMapper, FamilySource> implements IFamilySourceService {

    private final int TYPE_PARENT = 0;
    private final int TYPE_CHILD = 1;
    private final int TYPE_MATE = 2;

    @Override
    public boolean saveSource(FamilySource familySource) {
        int count = this.count(new LambdaQueryWrapper<FamilySource>().eq(FamilySource::getFamilyId, familySource.getFamilyId())
                .eq(FamilySource::getFamilySourcePid, 0L));
        if (count > 0) {
            throw new CustomException("当前家系已存在根节点");
        } else {
            familySource.setFamilySourcePid(0L);
        }
        return save(familySource);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean saveRelateSource(FamilySource familySource) {
        boolean result = false;
        if (familySource.getType() == TYPE_PARENT) {
            familySource.setFamilySourcePid(0L);
            result = this.save(familySource);
            // 新增父样本源 修改子样本源pid
            FamilySource childSource = this.getById(familySource.getFamilySourceCid());
            if (ObjectUtil.isNotEmpty(childSource)) {
                childSource.setFamilySourcePid(familySource.getFamilySourceId());
                this.updateById(childSource);
            }
        } else if (familySource.getType() == TYPE_CHILD) {
            // 新增子样本源
            result = this.save(familySource);
        } else if (familySource.getType() == TYPE_MATE) {
            result = this.save(familySource);
            // 新增配偶样本源 修改配偶样本源mid
            FamilySource mateSource = this.getById(familySource.getFamilySourceMid());
            if (ObjectUtil.isNotEmpty(mateSource)) {
                mateSource.setFamilySourceMid(familySource.getFamilySourceId());
                this.updateById(mateSource);
            }
        }
        return result;
    }

    @Override
    public FamilySource getInfoById(Long familySourceId) {
        FamilySource familySource = this.getById(familySourceId);
        // 获取父样本源
        FamilySource pSource = this.getOne(new LambdaQueryWrapper<FamilySource>()
                .eq(FamilySource::getFamilySourceId, familySource.getFamilySourcePid()).last("limit 1"));
        familySource.setParentSource(pSource);
        // 获取子样本源
        List<FamilySource> cSources = this.list(new LambdaQueryWrapper<FamilySource>()
                .eq(FamilySource::getFamilySourcePid, familySource.getFamilySourceId()));
        familySource.setChildren(cSources);
        // 获取配偶样本源
        List<FamilySource> mSource = this.list(new LambdaQueryWrapper<FamilySource>()
                .eq(FamilySource::getFamilySourceId, familySource.getFamilySourceMid()));
        familySource.setMate(mSource);
        return familySource;
    }

    @Override
    public boolean removeSourceById(Long familySourceId) {
        int count = this.count(new LambdaQueryWrapper<FamilySource>().eq(FamilySource::getFamilySourcePid, familySourceId));
        if (count > 0) {
            throw new CustomException("当前样本源存在子样本源，不允许删除");
        }
        return this.removeById(familySourceId);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean delRelateSource(FamilySource familySource) {
        if (familySource.getType() == TYPE_CHILD) {
            familySource.setFamilySourcePid(-1L);
        } else if (familySource.getType() == TYPE_MATE) {
            FamilySource mate = this.getById(familySource.getFamilySourceMid());
            mate.setFamilySourceMid(-1L);
            familySource.setFamilySourceMid(-1L);
            this.updateById(mate);
        }
        return this.updateById(familySource);
    }
}
